package com.wg.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wg.R;
import com.wg.entity.Scores;
import com.wg.entity.Users;
import com.wg.entity.dto.UserLoginDto;
import com.wg.entity.dto.UserRegisterDto;
import com.wg.entity.vo.MyScoreVo;
import com.wg.handler.WgException;
import com.wg.mapper.UserMapper;
import com.wg.service.ScoreService;
import com.wg.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, Users> implements UserService {

    @Autowired
    ScoreService scoreService;

    @Override
    public R register(UserRegisterDto user) {
        String password = user.getPassword();
        String rePassword = user.getRePassword();
        if (!password.equals(rePassword)) {
            throw new WgException(400, "密码不一致");
        }
        LambdaQueryWrapper<Users> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Users::getName, user.getName());
        Users dbUser = getOne(wrapper);
        if (dbUser != null) {
            throw new WgException(403, "用户名重复");
        }
        Users newUser = new Users();
        newUser.setName(user.getName()).setPassword(user.getPassword()).setJobId(user.getJobId());
        newUser.setBrief("这家伙很懒，什么都没有留下");
        save(newUser);
        return R.ok();
    }

    @Override
    public R<Users> login(UserLoginDto user, HttpServletRequest request) {
        Users dbUser = queryUserByNameAndPwd(user.getName(), user.getPassword());
        if (dbUser == null) {
            throw new WgException(403, "用户名或密码错误");
        }
        request.getSession().setAttribute("user", dbUser);
        return R.ok(dbUser);
    }

    @Override
    public R<MyScoreVo> getMyScore(Long id) {
        LambdaQueryWrapper<Users> uWrapper = new LambdaQueryWrapper<>();
        uWrapper.eq(Users::getId, id);
        Users user = getOne(uWrapper);

        Scores score = getScoreByUser(id);
        MyScoreVo vo = parseScore(score, user);

        return R.ok(vo);
    }

    public Scores getScoreByUser(Long userId) {
        LambdaQueryWrapper<Scores> sWrapper = new LambdaQueryWrapper<>();
        sWrapper.eq(Scores::getUserId, userId);
        return scoreService.getOne(sWrapper);
    }

    public MyScoreVo parseScore(Scores score, Users user) {
        MyScoreVo vo = new MyScoreVo();
        vo.setUserName(user.getName()).setUserId(user.getId());
        if (score == null) {
            vo.setScore(0);
        } else {
            vo.setScore(score.getScore());
        }
        return vo;
    }

    @Override
    public R<List<MyScoreVo>> getAllScore() {
        List<MyScoreVo> myScores = new ArrayList<>();
        List<Users> users = list();
        for (Users user : users) {
            Scores score = getScoreByUser(user.getId());
            myScores.add(parseScore(score, user));
        }
        myScores = myScores.stream().sorted(
                Comparator.comparing(MyScoreVo::getScore).reversed()
        ).collect(Collectors.toList());
        return R.ok(myScores);

    }

    public Users queryUserByNameAndPwd(String userName, String password) {
        LambdaQueryWrapper<Users> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Users::getName, userName).eq(Users::getPassword, password);
        return getOne(wrapper);
    }
}
